# coding=utf-8
# 全世界最帅的帅哥
import logging
import logging.handlers
import os
from datetime import date
from flask import request


class RequestSubjectFormatter(logging.Formatter):
    """
    自定义的日志输出格式
    """

    def format(self, record):
        record.url = request.url  # 需要在日志中记录请求地址
        record.remote_addr = request.remote_addr
        # 这里显示python2会报错 python2的super要传入参数 尽量使用python3
        return super().format(record)


# Logger: 可供程序直接调用的接口，app通过调用提供的api来记录日志
# Handlers: 决定将日志记录分配至正确的目的地
# Filters:对日志信息进行过滤， 提供更细粒度的日志是否输出的判断
# Formatters: 制定最终记录打印的格式布局
def create_logger(app):
    """
    设置日志配置
    :param app: 项目中的app对象
    :return:
    """
    # 日志的默认等级
    logging_level = app.config["LOGGING_LEVEL"]
    # 日志的配置目录
    logging_file_dir = app.config["LOGGING_FILE_DIR"]
    # 日志文件的最大大小
    logging_file_max_bytes = app.config["LOGGING_FILE_MAX_BYTES"]
    # 日志的最大个数
    logging_backup = app.config["LOGGING_BACKUP"]

    # 设置日志的输出格式（针对文件）
    request_formatter = RequestSubjectFormatter(
        '%(asctime)s %(remote_addr)s 请求 %(url)s 的 %(funcName)s %(levelname)s 在 %(module)s %(lineno)d : %(message)s'
    )

    if os.path.isdir(logging_file_dir):
        pass
    else:
        os.mkdir(logging_file_dir)

    d = date.today()
    # 为了让一个进程操作一个文件 文件名加上当前进程的ID
    subject_file_handler = logging.handlers.RotatingFileHandler(
        filename=os.path.join(logging_file_dir, d.strftime("%Y-%m-%d_") + 'subject' + ".log"),
        maxBytes=logging_file_max_bytes, backupCount=logging_backup, encoding="utf8")

    # 给当前的handler设置格式
    subject_file_handler.setFormatter(request_formatter)
    # 得到一个logger对象
    # getLogger必须写项目的名字
    subject_logger = logging.getLogger(__name__)
    # 日志发送到文件
    subject_logger.addHandler(subject_file_handler)
    subject_logger.setLevel(logging_level)

    # 发送到控制台的handler
    subject_console_handler = logging.StreamHandler()
    subject_console_handler.setFormatter(
        logging.Formatter('%(asctime)s %(levelname)s 在 %(module)s %(lineno)d: %(message)s')
    )

    # 当项目运行debug模式，才用控制台输出
    if app.debug:
        subject_logger.addHandler(subject_console_handler)

    return subject_logger
